#include<iostream>
#include<string>
#include <fstream>
#include<vector>
#include<map>
using namespace std;

map<string,string> Principle; //={{"const","CONSTTK"},{"int","INTTK"},{"char","CHARTK"},{"void","VOIDTK"},{"main","MAINTK"},{"if","IFTK"},{"else","ELSETK"},{"do","DOTK"},{"while","WHILETK"},{"for","FORTK"},{"scanf","SCANFTK"},{"printf","PRINTFTK"},{"return","RETURNTK"},{"+","PLUS"},{"-","MINU"},{"*","MULT"},{"/","DIV"},{"<","LSS"},{"<=","LEQ"},{">","GRE"},{">=","GEQ"},{"==","EQL"},{"!=","NEQ"},{"=","ASSIGN"},{";","SEMICN"},{",","COMMA"},{"(","LPARENT"},{")","RPARENT"},{"[","LBRACK"},{"]","RBRACK"},{"{","LBRACE"},{"}","RBRACE"},{"\"","STRCON"},{"\'","CHARCON"},{"INTCON","INTCON"}};
void initializeP(){
    //初始化map
    Principle["const"]="CONSTTK";
    Principle["int"]="INTTK";
    Principle["char"]="CHARTK";
    Principle["void"]="VOIDTK";
    Principle["main"]="MAINTK";
    Principle["if"]="IFTK";
    Principle["else"]="ELSETK";
    Principle["do"]="DOTK";
    Principle["while"]="WHILETK";
    Principle["for"]="FORTK";
    Principle["scanf"]="SCANFTK";
    Principle["printf"]="PRINTFTK";
    Principle["return"]="RETURNTK";
    Principle["+"]="PLUS";
    Principle["-"]="MINU";
    Principle["*"]="MULT";
    Principle["/"]="DIV";
    Principle["<"]="LSS";
    Principle["<="]="LEQ";
    Principle[">"]="GRE";
    Principle[">="]="GEQ";
    Principle["=="]="EQL";
    Principle["!="]="NEQ";
    Principle["="]="ASSIGN";
    Principle[";"]="SEMICN";
    Principle[","]="COMMA";
    Principle["("]="LPARENT";
    Principle[")"]="RPARENT";
    Principle["["]="LBRACK";
    Principle["]"]="RBRACK";
    Principle["{"]="LBRACE";
    Principle["}"]="RBRACE";
    Principle["\""]="STRCON";
    Principle["\'"]="CHARCON";
    Principle["INTCON"]="INTCON";
}
string getdate(){   //从文件中读取数据
    string date;
    ifstream inFile;
    inFile.open("testfile.txt",ios::in);
    if(inFile){
        printf("文件打开成功，正在读取文件数据\n");
        string buffer;
        // stringstream buffer;            // stringstream object
        // buffer << inFile.rdbuf();
        while(getline(inFile,buffer)){
            date+=buffer;
            date+='\n';
        }

        printf("数据读取完毕\n");
        inFile.close();
        printf("文件关闭\n");
    }
    return date;
}
bool isNumber(char c){   //这里没有考虑小数，如果考虑小数的话.应该也属于数字
    if(c>='0'&&c<='9')
        return true;
    else return false;
}
bool isUnder(char c){  //是否为下划线
    if(c=='_')
        return true;
    else 
        return false;
}
bool isLetter(char c){   //是否是字母
    if((c>='a'&&c<='z')||(c>='A'&&c<='Z'))
        return true;
    else 
        return false;
}
bool isDoubleSymbol(char c){ //双个运算符
    if(c=='<'||c=='>'||c=='='||c=='!')
        return true;
    else
        return false;
}
bool isSignalSymbol(char c){ //单个运算符
    if(c=='+'||c=='-'||c=='*'||c=='/'||c==';'||c==','||c=='('||c==')'||c=='['||c==']'||c=='{'||c=='}')
        return true;
    else return false;
} 
bool isStr(char c){   //因为字符串是”开头，所以判断是否是字符串判断“，中间的内容是字符串的内容，判断字符也是同理
    if(c=='"')
        return true;
    else 
        return false; 
}
bool isChar(char c){
    if(c=='\'')
        return true;
    else return false;
}
string JudgeKind(string c){  //根据分过的单词来判断其类别
    string Kind;
    if(Principle.find(c) != Principle.end())
        Kind=Principle[c];
    else Kind="IDENFR";
    return Kind;
}
void SplitWord(vector<string> &date,vector<string> &date2,const char * str,int n){
    //分词 date容器存储单词类别码，date2容器存储 单词内容
    //temp 存储map的key值，  temp2存储单词内容
    //题目中共有 字符串、字母单词类别，数字常量，
    for(int i=0;i<n;i++){
        string temp;
        string temp2;
        if(isSignalSymbol(str[i]))  //判断是否为单个的运算符
            temp=str[i];
            temp2=temp;
            //cout<<temp<<":"<<str[i]<<endl;
        if(isDoubleSymbol(str[i])){  //判断是否为双个运算符
            temp+=str[i];
            if(isDoubleSymbol(str[i+1])){
                temp+=str[i+1];
                i++;
            }
            temp2=temp;
            //cout<<temp<<":"<<str[i]<<endl;
        }
        if(isStr(str[i])){   //判断是否为字符串，
            i++;
            while(!isStr(str[i])){
                temp2+=str[i];
                i++;
            }
            temp="\"";
            
            //cout<<temp<<":"<<str[i]<<endl;
        }
        if(isChar(str[i])){  //判断是否为字符常量，这里假设字符常量没有错误，只有一个字符
            temp="\'";
            temp2=str[i+1];
            i+=2;
            //cout<<temp<<":"<<str[i]<<endl;
        }
        if(isNumber(str[i])){ 
            temp="INTCON";
            temp2+=str[i];
            i++;
            while(isNumber(str[i])){
                temp2+=str[i];
                i++;
            }
            i--;
            //cout<<temp<<":"<<str[i]<<endl;
        }
        if(isLetter(str[i])||isUnder(str[i])){
            temp+=str[i];
            i++;
            while(isLetter(str[i])||isNumber(str[i])||isUnder(str[i])){
                temp+=str[i];
                i++;
            }
            i--;
            //cout<<temp<<":"<<str[i]<<endl;
            temp2=temp;
        }
        if(temp!="")
        {   date.push_back(JudgeKind(temp));
            date2.push_back(temp2);
        }
    }
}

int main(){
    initializeP();
    //map<string,string> Principle={{"const","CONSTTK"},{"int","INTTK"},{"char","CHARTK"},{"void","VOIDTK"},{"main","MAINTK"},{"if","IFTK"},{"else","ELSETK"},{"do","DOTK"},{"while","WHILETK"},{"for","FORTK"},{"scanf","SCANFTK"},{"printf","PRINTFTK"},{"return","RETURNTK"},{"+","PLUS"},{"-","MINU"},{"*","MULT"},{"/","DIV"},{"<","LSS"},{"<=","LEQ"},{">","GRE"},{">=","GEQ"},{"==","EQL"},{"!=","NEQ"},{"=","ASSIGN"},{";","SEMICN"},{",","COMMA"},{"(","LPARENT"},{")","RPARENT"},{"[","LBRACK"},{"]","RBRACK"},{"{","LBRACE"},{"}","RBRACE"},{"\"","STRCON"},{"\'","CHARCON"},{"INTCON","INTCON"}};
    string str=getdate();
    const char * cstr=str.c_str();
    int n=str.length();
    cout<<cstr<<endl;
    vector<string> date;
    vector<string> date2;
    SplitWord(date,date2,cstr,n);
    
    ofstream outFile;
    outFile.open("output.txt",ofstream::out);
    for(int i=0;i<date.size();i++){
        outFile<<date[i]<<" "<<date2[i]<<endl;
    }
}